package com.sword.ms_bwk.block.tile;

import com.sword.ms_bwk.Utils;
import com.sword.ms_bwk.block.FurnitureBlock;
import com.sword.ms_bwk.network.NetworkOfFurnitureCloseSound;
import net.minecraft.core.BlockPos;
import net.minecraft.core.NonNullList;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.chat.TranslatableComponent;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.world.ContainerHelper;
import net.minecraft.world.MenuProvider;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.ChestMenu;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.block.entity.BlockEntity;
import net.minecraft.world.level.block.entity.BlockEntityType;
import net.minecraft.world.level.block.entity.RandomizableContainerBlockEntity;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraftforge.network.PacketDistributor;
import software.bernie.geckolib3.core.IAnimatable;
import software.bernie.geckolib3.core.PlayState;
import software.bernie.geckolib3.core.builder.AnimationBuilder;
import software.bernie.geckolib3.core.builder.ILoopType;
import software.bernie.geckolib3.core.controller.AnimationController;
import software.bernie.geckolib3.core.event.predicate.AnimationEvent;
import software.bernie.geckolib3.core.manager.AnimationData;
import software.bernie.geckolib3.core.manager.AnimationFactory;
import software.bernie.geckolib3.util.GeckoLibUtil;

public class ContainerFurnitureBlockEntity extends RandomizableContainerBlockEntity implements IAnimatable, MenuProvider {
    private AnimationFactory factory = GeckoLibUtil.createFactory(this);
    private BlockPos pPos;
    private BlockState pState;
    private NonNullList<ItemStack> items = NonNullList.withSize(27, ItemStack.EMPTY);
    private FurnitureBlock block;

    public ContainerFurnitureBlockEntity(BlockEntityType<?> pEntity, FurnitureBlock block, BlockPos pPos, BlockState pState) {
        super(pEntity, pPos, pState);
        this.pPos = pPos;
        this.pState = pState;
        this.block = block;
    }

    //动画控制器
    @Override
    public void registerControllers(AnimationData data) {
        data.addAnimationController(new AnimationController<>(this, "controller", 0, this::predicate));
    }

    //动画内容逻辑
    private <E extends BlockEntity & IAnimatable> PlayState predicate(AnimationEvent<E> event) {
        event.getController().setAnimation(getBlockState().getValue(block.getOpenState()) ? new AnimationBuilder().addAnimation(block.getAnime(0), ILoopType.EDefaultLoopTypes.PLAY_ONCE).addAnimation(block.getAnime(1), ILoopType.EDefaultLoopTypes.LOOP) : new AnimationBuilder().addAnimation(block.getAnime(2), ILoopType.EDefaultLoopTypes.PLAY_ONCE));
        return PlayState.CONTINUE;
    }

    //返回动画工厂
    @Override
    public AnimationFactory getFactory() {
        return this.factory;
    }

    //设置容器id
    @Override
    protected Component getDefaultName() {
        return new TranslatableComponent("gui." + Utils.MOD_ID + "." + block.getFurnitureName());
    }

    //创建容器GUI
    @Override
    protected AbstractContainerMenu createMenu(int pContainerId, Inventory pInventory) {
        return ChestMenu.threeRows(pContainerId, pInventory, this);
    }

    //返回容器大小
    @Override
    public int getContainerSize() {
        return 27;
    }

    //设置家具改变形态
    @Override
    public void setItem(int pIndex, ItemStack pStack) {
        super.setItem(pIndex, pStack);
        if (level == null) {
            return;
        }
        pState = pState.setValue(block.setKeepState(), Boolean.valueOf(!isEmpty())).setValue(block.getOpenState(), Boolean.valueOf(true));
        level.setBlock(pPos, pState, 2);
    }

    //修改容器内容
    @Override
    protected NonNullList<ItemStack> getItems() {
        return this.items;
    }
    @Override
    protected void setItems(NonNullList<ItemStack> pItemStacks) {
        this.items = pItemStacks;
    }

    //关闭打开容器事件
    int usePlayer = 0;
    @Override
    public void startOpen(Player pPlayer) {
        usePlayer++;
    }
    @Override
    public void stopOpen(Player pPlayer) {
        usePlayer--;
        if (usePlayer <= 0) {
            pState = pState.setValue(block.getOpenState(), Boolean.valueOf(false));
            level.setBlock(pPos, pState, 2);
            NetworkOfFurnitureCloseSound.CHANNEL.send(PacketDistributor.PLAYER.with(() -> (ServerPlayer) pPlayer), new NetworkOfFurnitureCloseSound.SendPack(pPos));
            usePlayer = 0;
        }
    }

    //nbt保存读取
    @Override
    public void load(CompoundTag pTag) {
        super.load(pTag);
        this.items = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY);
        if (!this.tryLoadLootTable(pTag)) {
            ContainerHelper.loadAllItems(pTag, this.items);
        }
    }
    @Override
    protected void saveAdditional(CompoundTag pTag) {
        super.saveAdditional(pTag);
        if (!this.trySaveLootTable(pTag)) {
            ContainerHelper.saveAllItems(pTag, this.items);
        }
    }

    public FurnitureBlock getBlock() {
        return block;
    }
}
